#include <malloc.h>
#include <QtMath>
#include <QDebug>

#include "include/task.h"
#include "include/core.h"
#include "include/simul.h"
#define max 10

int get_tasknum()
{int task_num;
for(task_num=0;taskSets[task_num].task_id!=0;task_num++)
   {
    }
  return task_num+1;
}
void initAccessControl(int id, struct subsection partition,int peroid,int num_subscetion,int task_type)
{
     taskSets[id-1].isAccessControl=true;
     taskSets[id-1].task_id = id;
     taskSets[id-1].task_period = peroid;
     taskSets[id-1].num_subsection=num_subscetion;
     taskSets[id-1].task_type=task_type;
     for(int i=0;i<100;i++)
     {taskSets[id-1].partition.part_on_core[i] = partition.part_on_core[i];
      taskSets[id-1].partition.part_length[i] = partition.part_length[i];
      taskSets[id-1].partition.start[i] = partition.start[i];
     }
}

void enqueue_wait_for_join(Task *task)
{
    task_queue_node *New = new task_queue_node;
    New->task = task;
    task_queue_node *pos;
    task_queue_node *head = wait_for_join;

    for(pos = head->next; pos != head; pos = pos->next){
        if(pos->task->task_priority == task->task_priority){
            if(pos->task->task_deadline > task->task_deadline){
                add_task_list(New, pos->pre, pos);
                return;
            }
        }
        else if(pos->task->task_priority > task->task_priority){
            add_task_list(New, pos->pre, pos);
            return;
        }
    }
    add_task_list_tail(New, head);
    return;
}


void dequeue_wait_for_join(Task *task)
{
    ready_queue_node *pos;
    ready_queue_node *head = wait_for_join;

    for(pos = head->next; pos != head; pos = pos->next){
        if(pos->task == task){
            del_task_list(pos->pre, pos->next);
            delete pos;
            return;
        }
    }
}

void initTask(int id, struct subsection partition,int peroid,int num_subsection,int tasktype)
{
   taskSets[id-1].task_id = id;
    taskSets[id-1].task_period = peroid;
    taskSets[id-1].num_subsection=num_subsection;
    taskSets[id-1].task_type=tasktype;
    taskSets[id-1].task_priority=10000;
    for(int i=0;i<100;i++)
    {taskSets[id-1].partition.part_on_core[i] = partition.part_on_core[i];
     taskSets[id-1].partition.part_length[i] = partition.part_length[i];
     taskSets[id-1].partition.start[i] = partition.start[i];
    }

    qDebug() <<"task"<<id<<endl;

    for(int i=0;i<100;i++)
     if(taskSets[id-1].partition.part_length[i]!=0)
     qDebug()<<"partition"<<taskSets[id-1].partition.part_on_core[i]<<"seg:S"<<i<<"start"<<taskSets[id-1].partition.start[i]<<"last"<<taskSets[id-1].partition.part_length[i]<<endl;

}




bool is_in_task_list(Task *cur, task_queue_node *head)
{
    task_queue_node *pos;
    for(pos = head->next; pos != head; pos = pos->next)
        if(pos->task == cur)
            return true;

    return false;
}

bool isExit(Task *current)
{
    if(current->execute_time == current->task_wcet)
        return true;
    else if(current->execute_time < current->task_wcet)
        return false;
    else{
        printf("Error: In IsExit(),  Task%d should exit\n", current->task_id);
        exit(0);
    }
}

bool isTaskArrival(int time, Task *task)
{
    if(task->arrival_time == time)
        return true;
    else
        return false;
}

bool isOnCore(Task *task, Core *core)
{
    if(task->on_core == core->core_id || (task->owner_cluster == core->owner_cluster && task->owner_cluster != -1))
        return true;
    else
        return false;
}


void initTask(int id, int type, int prior, int jitter, int wcet, int period, int ddl, int arrival_time)
{
    taskSets[id-1].task_id = id;
    taskSets[id-1].task_type = type;
    taskSets[id-1].task_priority = prior;
    taskSets[id-1].task_jitter = jitter;
    taskSets[id-1].task_wcet = wcet;
    taskSets[id-1].task_period = period;
    taskSets[id-1].task_deadline = ddl;
    taskSets[id-1].owner_cluster = -1;
    taskSets[id-1].arrival_time = arrival_time;
    taskSets[id-1].ready_time = arrival_time + jitter;
    taskSets[id-1].execute_time = 0;
    taskSets[id-1].isArrived = false;
    taskSets[id-1].first_release = true;
}

void initMRTSTask(int id, int type, int prior, int jitter, int wcet, int period, int ddl, int arrival_time,int on_core,int joined_row)
{
    taskSets[id-1].task_id = id;
    taskSets[id-1].task_type = type;
    taskSets[id-1].task_priority = prior;
    taskSets[id-1].task_jitter = jitter;
    taskSets[id-1].task_wcet = wcet;
    taskSets[id-1].task_period = period;
    taskSets[id-1].task_deadline = ddl;
    taskSets[id-1].on_core = on_core;
    taskSets[id-1].joined_row = joined_row;
    taskSets[id-1].owner_cluster = -1;
    taskSets[id-1].arrival_time = arrival_time;
    taskSets[id-1].ready_time = arrival_time + jitter;
    taskSets[id-1].execute_time = 0;
    taskSets[id-1].isArrived = false;
    taskSets[id-1].isRestart = false;
    taskSets[id-1].owner_cluster=cores[on_core].owner_cluster;
    taskSets[id-1].task_wcrt= ddl;
    taskSets[id-1].first_release = true;
    taskSets[id-1].num_subsection = 1;

}

void taskset_delet(Task *task)
{
    int temp=0;
    for(int i=0;i<get_tasknum();i++)
       if(taskSets[i].task_id==task->task_id)
       {temp=i;break;}

    for(int i=temp;i<get_tasknum()-1;i++)
    {taskSets[i]=taskSets[i+1]; taskSets[i].task_id--;}
}
